﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static _06_AOP.PipelineExample;
using static System.Net.Mime.MediaTypeNames;

namespace _06_AOP
{
    internal class PipelineExample
    {
        public delegate Task RequestDelegate(HttpContext context);

        public class HttpContext
        {

        }

        public class ApplicationBuilder
        {
            private readonly List<Func<RequestDelegate, RequestDelegate>> _components = new();

            public void Use(Func<RequestDelegate, RequestDelegate> middleware)
            {
                _components.Add(middleware);
            }

            public void Use(Func<HttpContext, Func<Task>, Task> middleware)
            {
                _components.Add((next) =>
                {
                    return async c =>
                    {
                        await middleware(c, () => next(c));
                    };
                });
            }

            public void Use(Func<HttpContext, RequestDelegate, Task> middleware)
            {
                _components.Add((next) =>
                {
                    return async c =>
                    {
                        await middleware(c, next);
                    };
                });
            }

            public void Run(RequestDelegate handler)
            {
                _components.Add((next) =>
                {
                    return async c =>
                    {
                        await handler(c);
                    };
                });
            }
            public RequestDelegate Build()
            {
                RequestDelegate app = c =>
                {
                    throw new InvalidOperationException("无效的管道");
                };
                for (int i = _components.Count - 1; i > -1; i--)
                {
                    app = _components[i](app);
                }
                return app;
            }
        }

        public interface IChain
        {
            Task NextAsync();
        }
        public class FilterChain : IChain
        {
            private readonly IFilter _filter;
            private readonly HttpContext _context;
            private readonly IChain _next;
            public FilterChain(IFilter filter, HttpContext context, IChain next)
            {
                _filter = filter;
                _context = context;
                _next = next;
            }
            public async Task NextAsync()
            {
                await _filter.InvokeAsync(_context, _next);
            }
        }
        public class ServletChain : IChain
        {
            private readonly IServlet _servlet;
            private readonly HttpContext _context;

            public ServletChain(IServlet servlet, HttpContext context)
            {
                _servlet = servlet;
                _context = context;
            }

            public async Task NextAsync()
            {
                await _servlet.DoPostAsync(_context);
            }
        }
        public interface IFilter
        {
            Task InvokeAsync(HttpContext context, IChain chain);
        }
        public class Filter1 : IFilter
        {
            public async Task InvokeAsync(HttpContext context, IChain chain)
            {
                Console.WriteLine("身份认证开始");
                await chain.NextAsync();
                Console.WriteLine("身份认证结束");
            }
        }
        public class Filter2 : IFilter
        {
            public async Task InvokeAsync(HttpContext context, IChain chain)
            {
                Console.WriteLine("授权认证开始");
                await chain.NextAsync();
                Console.WriteLine("授权认证结束");
            }
        }
        public interface IServlet
        {
            Task DoPostAsync(HttpContext context);
        }
        public class HelloServlet : IServlet
        {
            public Task DoPostAsync(HttpContext context)
            {
                Console.WriteLine("Hello World");
                return Task.CompletedTask;
            }
        }
        public class WebHost
        {
            private readonly List<IFilter> _filters = new List<IFilter>();

            public void AddFilter(IFilter filter)
            {
                _filters.Add(filter);
            }

            public void Exeucte(HttpContext context, IServlet servlet)
            {
                //自行处理filter为空的情况,就是直接执行serlvet就好了
                var stack = new Stack<IFilter>(_filters);
                var filter = stack.Pop();
                var chain = GetFilterChain(context, servlet,stack);
                filter.InvokeAsync(context, chain);
            }

            private IChain GetFilterChain(HttpContext context, IServlet servlet, Stack<IFilter> filters)
            {
                if (filters.Any())
                {
                    var filter = filters.Pop();
                    var next = GetFilterChain(context, servlet, filters);
                    return new FilterChain(filter, context, next);
                }
                else
                {
                    return new ServletChain(servlet, context);
                }
            }
        }
    }
}
